package com.aiwiown.snackmq.management;

import com.aiwiown.snackmq.common.metrics.MessageMetricEmitter;
import com.aiwiown.snackmq.network.connection.ConnectionManager;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
 * Broker 性能指标的聚合器和暴露点。
 */
@Getter
@Slf4j
public class BrokerMetrics {

    private final MessageMetricEmitter messageMetricEmitter = new MessageMetricEmitter();

    // --- 新增：用于计算集群范围 TPS 的状态字段 ---
    // 上一次计算时的集群总消息数
    private long lastTotalMessageCount = -1;
    // 上一次计算时的时间戳
    private long lastTpsCalcTimestamp = -1;

    public void registerConnectionMetrics(ConnectionManager instance) {
        // Placeholder for real implementation, e.g., using gauges to track connections
    }

    /**
     * 【新增】获取 Broker 的总 TPS（每秒事务数）。
     * 此方法从底层的 MessageMetricEmitter 获取一分钟内的平均速率。
     * **注意**：这只是单个节点的本地 TPS，而非整个集群的。
     *
     * @return TPS 值
     */
    public double getTps() {
        return this.messageMetricEmitter.getOneMinuteRate();
    }

    /**
     * 【新增】获取自 Broker 启动以来已生产的总消息数。
     * 此方法对于自动扩展和监控至关重要。
     * **注意**：这只是单个节点处理的消息数，而非整个集群的。
     *
     * @return 生产的消息总数
     */
    public long getTotalMessagesProduced() {
        return this.messageMetricEmitter.getTotalCount();
    }

    /**
     * 【最终修复】根据整个集群的消息总数变化，计算并返回全局 TPS。
     * 此方法是线程安全的，由 GetClusterOverviewHandler 调用。
     *
     * @param currentTotalClusterMessages 从数据状态机获取的、在集群中已同步的全局消息总数。
     * @return 集群的全局 TPS。
     */
    public synchronized double calculateClusterTps(long currentTotalClusterMessages) {
        // 首次调用时，初始化基准数据
        if (lastTotalMessageCount == -1) {
            lastTotalMessageCount = currentTotalClusterMessages;
            lastTpsCalcTimestamp = System.currentTimeMillis();
            return 0.0;
        }

        long now = System.currentTimeMillis();
        long timeDelta = now - lastTpsCalcTimestamp;

        // 如果时间间隔太短，或者消息总数没有增加（或减少，如数据清理），则返回 0，避免数值抖动。
        if (timeDelta < 1000 || currentTotalClusterMessages <= lastTotalMessageCount) {
            if (currentTotalClusterMessages < lastTotalMessageCount) {
                log.warn("Cluster message count decreased from {} to {}. Resetting TPS calculation baseline.", lastTotalMessageCount, currentTotalClusterMessages);
            }
            lastTotalMessageCount = currentTotalClusterMessages;
            lastTpsCalcTimestamp = now;
            return 0.0;
        }

        long messageDelta = currentTotalClusterMessages - lastTotalMessageCount;
        double tps = (double) messageDelta * 1000.0 / timeDelta;

        // 更新状态以备下次计算
        lastTotalMessageCount = currentTotalClusterMessages;
        lastTpsCalcTimestamp = now;

        return tps;
    }
}